home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
serial
/
zyxel-1.5-s
/
zyxel-1
/
zplay
/
zplay.c
< prev
Wrap
C/C++ Source or Header
|
1994-10-06
|
7KB
|
278 lines
/*
zplay, play Zyxel zad files.
Autor: Michael Beck - beck@informatik.hu-berlin.de
*/
#include <stdio.h>
#include <malloc.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#ifndef __STDC__
#include <getopt.h>
#endif /* __STDC__ */
#include <fcntl.h>
#include "dsp.h"
/* global data */
char * command;
/* Local prototypes */
int play (int audio, char * fname );
int readzad(int voice, FILE * ifile);
void ToVoc(int audio,int Vdata);
void Adaptive(char DataBit);
/* And here we are */
int main (int argc, char *argv[]) {
char c;
int openct=100,audio,volume,dspspeed=DEFAULT_DSP_SPEED,samplesize=8,abuf;
/* Save the program name for use in error messages */
command = argv[0];
while ((c = getopt (argc, argv, "qs:b:v:")) != EOF)
switch (c) {
case 's':
dspspeed = atoi (optarg);
if (dspspeed < 300)
dspspeed *= 1000;
break;
case 'b':
samplesize = atoi (optarg);
break;
case 'q':
verbose=!verbose;
break;
case 'v':
volume = atoi (optarg);
break;
default:
fprintf (stderr, "Usage: %s [-s Hz] [-b 8|12|16] <filename>\n", argv[0]);
exit (-1);
}
/* We will loop <openct> times, with 1 sec delay */
while(openct--) {
if((audio = open (AUDIO, O_WRONLY, 0))!=-1)
break;
if(errno!=EBUSY) {
perror (AUDIO);
exit (-1);
}
if(verbose)
printf("[%4d] waiting\n",getpid());
sleep(1);
}
if(verbose)
printf("[%4d] start\n",getpid());
/* Allocate buffers for memory */
dsp_init(audio);
/* Sync the DSP */
sync_dsp(audio);
/* sync_dsp(audio); */
set_dsp_speed(audio,dspspeed);
set_dsp_samplesize(audio,samplesize);
/* Play the file */
play(audio,argv[optind++]);
close_dsp(audio);
if(verbose)
printf("[%4d] done\n",getpid());
return 0;
}
/* copy the file until EOF */
int play (int audio, char * fname ) {
FILE * ifile;
/* Open the source file */
if((ifile=fopen(fname,"rb"))==NULL) {
fprintf(stderr,"%s unable to open input\n", command);
perror(fname);
return -1;
}
/* Play zad file */
readzad(audio,ifile);
fclose(ifile);
}
/* Conversion variables */
char CompBit;
long EstMax,Delta,Data,Pack;
int MaxTbl1[] = { 0x3800, 0x5600 } ;
int MaxTbl2[] = { 0x399A, 0x3A9F, 0x4D14, 0x6607 } ;
int MaxTbl3[] = { 0x3556, 0x3556, 0x399A, 0x3A9F,
0x4200, 0x4D14, 0x6607, 0x6607 } ;
int *MaxTbl = MaxTbl2;
/* -------------------------------- */
/* ZyXEL ADPCM -> .VOC conversion */
/* -------------------------------- */
int readzad(int audio, FILE * ifile) {
char ZheadBuf0[16] ;
char ZheadBuf1[16] = { 'Z','y','X','E','L',2,0,0,0,0,0,0,0,0,0,0 } ;
/* Read from source file */
if( fread(ZheadBuf0,sizeof(char),16,ifile)!=16) {
fprintf(stderr,"%s zad file without header\n", command);
perror(command);
return -1;
}
/* compare with the expected header */
if ( strncmp( ZheadBuf0, ZheadBuf1, 6)) {
fprintf(stderr,"%s incorrect zad file\n", command);
perror(command);
return -1;
}
/* Parameters */
Delta=5;
EstMax=0;
/* Change from 2-bit to 3-bit ADPCM */
CompBit = ZheadBuf0[10] ;
switch ( CompBit )
{
case 1:
MaxTbl = MaxTbl1;
if(verbose)
printf("2-bit ADPCM\n");
break;
case 2:
MaxTbl = MaxTbl2;
if (verbose)
printf("3-bit ADPCM\n");
break;
case 3:
MaxTbl = MaxTbl3;
Delta=4;
if (verbose)
printf("4-bit ADPCM\n");
break;
}
while ((Data=getc(ifile)) != EOF ) {
switch ( CompBit )
{
case 1:
ToVoc(audio,(Data&0xc0)>>6) ; /* XX-- ---- */
ToVoc(audio,(Data&0x30)>>4) ; /* --XX ---- */
ToVoc(audio,(Data&0x0c)>>2) ; /* ---- XX-- */
ToVoc(audio,Data&0x03) ; /* ---- --XX */
break;
case 2:
ToVoc(audio,(Data&0xe0)>>5) ; /* XXX- ---- */
ToVoc(audio,(Data&0x1c)>>2) ; /* ---X XX-- */
Pack = (Data&0x03)<<1 ;
Data = getc(ifile);
ToVoc(audio,Pack|((Data&0x80)>>7)) ;
ToVoc(audio,(Data&0x70)>>4) ; /* -XXX ---- */
ToVoc(audio,(Data&0x0e)>>1) ; /* ---- XXX- */
Pack = (Data&0x01)<<2 ;
Data = getc(ifile);
ToVoc(audio,Pack|((Data&0xc0)>>6)) ;
ToVoc(audio,(Data&0x38)>>3) ; /* --XX X--- */
ToVoc(audio,Data&0x07) ; /* ---- -XXX */
break;
case 3:
ToVoc(audio,(Data&0xf0)>>4) ; /* XXXX ---- */
ToVoc(audio,Data&0x0f) ; /* ---- XXXX */
break;
}
}
}
/**************************************************************************
ToVoc()
Copyright 1992, ZyXEL Communications Corporation
************************************************************************/
void ToVoc(int audio, int Vdata)
{
int Wdata ;
Adaptive((char)Vdata) ;
if ( EstMax > 8191 )
Wdata = 8191 ;
else if ( EstMax < -8192 )
Wdata = -8192 ;
else
Wdata = EstMax ;
Wdata=((Wdata>>6)+128)&0xff;
write_dsp_byte(audio,Wdata);
/* write(audio,&Wdata,1); */
}
/**************************************************************************
Adaptive(DataBit, SignBit)
Copyright 1992, ZyXEL Communications Corporation
************************************************************************/
void Adaptive(char DataBit)
{
int TmpMax ;
char TmpData, SignBit ;
long TmpDelta ;
long t0 ;
/******* This part is modified for the Firmware > 6.10 **************/
/**/ t0 = (long)EstMax ; /**/
/**/ t0 *= 4093 ; /**/
/**/ t0 += 2048 ; /**/
/**/ t0 /= 4096 ; /**/
/**/ EstMax = (int)t0 ; /**/
/********************************************************************/
SignBit = DataBit & (1<<CompBit) ;
DataBit &= ~(1<<CompBit) ;
if ( (Delta&1) && !SignBit )
++EstMax ;
/* ------------------- */
/* Calculate the Delta */
/* ------------------- */
TmpDelta = Delta ;
TmpDelta *= MaxTbl[DataBit] ;
TmpDelta += 8192 ;
TmpDelta >>= 14 ;
/* -------------------- */
/* Calculate the EstMax */
/* -------------------- */
TmpMax = (Delta>>1) ;
while ( DataBit-- )
TmpMax += Delta ;
if ( SignBit )
EstMax -= TmpMax ;
else
EstMax += TmpMax ;
Delta = (int)TmpDelta ;
}